let f = (a, b) => ()
let greet = (~person, ~from as hometown) => ()
let greet = (~person="Steve", ~from as hometown="Cupertino") => ()

let onChangedVisible = (
  ~anchor=None,
  rbt,
  ~oldNewVisible,
  ~top as top_,
  ~bottom as bottom_,
  ~appear,
  ~remained,
  ~disappear,
) => () 

let greet = (~person, ~from as hometown) => superLongIdentifiiiiiieeeeeeerExpression()

let greet = (
  ~person,
  ~superLongIdentifiiiiiieeeeeeer as pat,
  ~superLongIdentifiiiiiieeeeeeer2 as pat2,
  ~from as hometown
) => superLongIdentifiiiiiieeeeeeerExpression()

let greet = (
  ~person,
  ~superLongIdentifiiiiiieeeeeeer as pat,
  ~superLongIdentifiiiiiieeeeeeer2 as pat2,
  ~from as hometown
) => superLongIdentislkdjflksjdfljslkjdflksjdklfjlskdjfklffiiiiiieeeeeeerExpression()

let greet = (
  ~person,
  ~superLongIdentifiiiiiieeeeeeer as pat,
  ~superLongIdentifiiiiiieeeeeeer2 as pat2,
  ~from as hometown
) => superLongIdentier

let greet = (
  ~person,
  ~superLongIdentifiiiiiieeeeeeer as pat,
  ~superLongIdentifiiiiiieeeeeeer2 as pat2,
  ~from as hometown
) => superLongIdentislkdjflksjdfljslkjdflksjdklfjlskdjfklffiiiiiieeeeeeerExpression

let greet = (
  ~person,
  ~superLongIdentifiiiiiieeeeeeer as pat,
  ~superLongIdentifiiiiiieeeeeeer2 as pat2,
  ~from as hometown
) => SuperLongConstructorrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr

let greet = (
  ~person,
  ~superLongIdentifiiiiiieeeeeeer as pat,
  ~superLongIdentifiiiiiieeeeeeer2 as pat2,
  ~from as hometown
) => SuperLongConstructorrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr

let f = () => ()
let f = a => ()
let f = _ => ()

let f = (~a=?) => ()
let f = (~from as hometown=?) => ()

let f = (. a) => ()
let f = (. a, b) => ()
let f = (. ()) => ()

let f = @attr (a, b) => @attr2 (c, d) => ()
let f = @attr (@attrOnA a, @attrOnB b) => @attr2 (@attrOnC c, @attrOnD d) => ()
let f = @attr (. a, b) => @attr2 (. c, d) => ()

let f = (@attr ~a, @attr ~b) => ()
let f = (. @attr ~a, . @attr ~b) => ()

let f = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => ()

let coordBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => {x: 1, y: 2}

let coordBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => {x: 1, y: 2}

let recordBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => {...fields, firstField: superLongIdentiiiiiiiifffffffiiiiieeeeeeeer, secondField: superLongIdentiiiiiiiifffffffiiiiieeeeeeeer, thirdField: superLongIdentiiiiiiiifffffffiiiiieeeeeeeer}

let arrayBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => [1, 2, 3, 4]

let arrayBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => [
  superLongIdentiiiiiiiifffffffiiiiieeeeeeeer,
  superLongIdentiiiiiiiifffffffiiiiieeeeeeeer,
  superLongIdentiiiiiiiifffffffiiiiieeeeeeeer,
]

let tupleBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => (1, 2, 3)

let tupleBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => (
  superLongIdentiiiiiiiifffffffiiiiieeeeeeeer,
  superLongIdentiiiiiiiifffffffiiiiieeeeeeeer,
  superLongIdentiiiiiiiifffffffiiiiieeeeeeeer,
)

let constrBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => Cartesian({
  x: Omega.x,
  y: Theta.y
})

let constrBuilder = (
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
  thisIsAVeryLongNaaaaaaaaaaaaaaaaaaameeeeeeeeeeeee,
) => Reducer(superLongIdentiiiiiiiifffffffiiiiieeeeeeeer, superLongIdentiiiiiiiifffffffiiiiieeeeeeeer, superLongIdentiiiiiiiifffffffiiiiieeeeeeeer)

let genName = () => "Steve"

@react.component
let make = (
      ~onChange: option<(. { "testing": bool}, array<string>) => unit>=?,
      children,
    ) => {
  let doSomething = () =>
    switch (onChange) {
    | None => ()
    | Some(onChange) => onChange(. {"testing": true}, ["hey"])
    };
  <input onChange={_ => doSomething()} />;
};

let add = (a, b): int => a + b

let add = (a, b): {"field1": int, "field2": string, "field3": int, "field4": int}  => a + b
let add = (superLongParameterName1, superLongParameterName2, superLongParameterName3): {"field1": int, "field2": string, "field3": int, "field4": int}  => a + b

let add = (superLongParameterName1, superLongParameterName2, superLongParameterName3): {
  "field1": int,
  "field2": string,
  "field3": int,
  "field4": int,
  "field5": int,
  }  => a + b

let add = ((a, b)): (int, string, int, int)  => a + b
let add = ((a, b)): (intWithSuperLongName, stringWithSuperLongName, intWithSuperLongName, intWithSuperLongName)  => a + b
let add = ((superLongParameterName, bsuperLongParameterName, superLongParameterName, superLongParameterName)): (intWithSuperLongName, stringWithSuperLongName, intWithSuperLongName, intWithSuperLongName)  => a + b

let add = (list{a, b}): list<intWithSuperLongName, stringWithSuperLongName, intWithSuperLongName, intWithSuperLongName>  => a + b
let add = (list{superLongParameterName, bsuperLongParameterName, superLongParameterName, superLongParameterName}): list<intWithSuperLongName, stringWithSuperLongName, intWithSuperLongName, intWithSuperLongName>  => a + b

let add = ([a, b]): array<intWithSuperLongName, stringWithSuperLongName, intWithSuperLongName, intWithSuperLongName>  => a + b
let add = ([superLongParameterName, bsuperLongParameterName, superLongParameterName, superLongParameterName]): array<intWithSuperLongName, stringWithSuperLongName, intWithSuperLongName, intWithSuperLongName>  => a + b

let add = ({x: superLongParameterName, y: superLongParameterName, z: superLongParameterName}) => x + y + z
let add = ({x: superLongParameterName, y: superLongParameterName, z: superLongParameterName}) => x + y + z
let add = ({x: x as superLongParameterName, y: y as superLongParameterName, z: z as superLongParameterName}) => x + y + z


let add = (Color(superLongParameterName, superLongParameterName, superLongParameterNameeeeeee)) => x + y + z
let add = (Color(superLongParameterName, superLongParameterName, superLongParameterNameeeee)) : color<superLongTypeIdent, superLongType2, anotherLongOne, woooooooooooooooooooooooooooooooooooow> => x + y + z

let parseExceptionDef = (~attrs, p) => {
  let startPos = p.Parser.startPos
  Parser.expect(Token.Exception, p)
  let (_, name, kind) = parseConstrDef(~parseAttrs=false, p)
  let loc = mkLoc(startPos, p.prevEndPos)
  Ast_helper.Te.constructor(~loc, ~attrs, name, kind)
}

and parseStructure = (p): Parsetree.structure =>
  parseList(p, ~grammar=Grammar.Structure, ~f=parseStructureItem)

and parseStructureItem = (_): Parsetree.structure_item => {
  let startPos = p.Parser.startPos
  let attrs = parseAttributes(p)
  attrs
}

// block expressions should have braces on the same line as the =>
let equals = (c1, c2) => {
  open Float
  c1.red->equals(c2.red) &&
  c1.blue->equals(c2.blue) &&
  c1.green->equals(c2.green)
}

let equals2 = (c1, c2) => {
  module B = Belt
  c1.red->equals(c2.red) &&
  c1.blue->equals(c2.blue) &&
  c1.green->equals(c2.green)
}

let equals3 = (c1, c2) => {
  let a = 1
  let b = 2
  c1.red->equals(c2.red) &&
  c1.blue->equals(c2.blue) &&
  c1.green->equals(c2.green)
}

let equals4 = (c1, c2) => {
  exception Foo
  c1.red->equals(c2.red) &&
  c1.blue->equals(c2.blue) &&
  c1.green->equals(c2.green)
}

// ~d: e should stay ~d: e
let a = (~b as c, ~d: e) => 1

let f = list => list()
let f = \"switch" => \"switch" + 20 

<div className="max-w-3xl mx-auto">
  <CoursesReview__SubmissionsTab
    updateSubmissionsCB={(~submissions, ~selectedTab, ~hasNextPage, ~totalCount, ~endCursor) =>
      send(SetSubmissions(submissions, selectedTab, hasNextPage, endCursor, totalCount))}
  />
</div>

let f = (~\"aria-b", ~\"aria-c") => {
  Js.log(\"aria-b", \"aria-c")
}

let f = (~\"aria-b": string, ~\"aria-d" as \"aria-xyz" ) => {
  Js.log(\"aria-b", \"aria-xyz")
}

let f = (type \"😎", x) => Js.log(x)

let query = (~url, ()): (unit => unit) => {
  () => Js.log("Queried " ++ url)
}

let query = (~url, ()): (unit => unit => unit) => {
  () => () => Js.log("Queried " ++ url)
}

let query = (~url, ()): (unit => unit => unit => unit) => {
  () => () => () => Js.log("Queried " ++ url)
}

let f = (. a) => (. b) => a + b
let f = (. a, b) => (. b, c) => a + b + c + d
let f = (. a, b) => (. b , c) => (. e , f, g) => a + b + c + d  + e + f + g

let unitConstraint = (): array<nullable<int>> => []
